package com.fc.redap.controller.api;

import com.fc.redap.dtos.LoginRequest;
import com.fc.redap.dtos.LoginResponse;
import com.fc.redap.dtos.ResponseJson;
import com.fc.redap.entity.SmsHistoryEntity;
import com.fc.redap.exception.ResponseException;
import com.fc.redap.helper.StringUtils;
import com.fc.redap.service.ISessionEntityService;
import com.fc.redap.service.ISmsHistoryService;
import com.fc.redap.shiro.realm.MyAuthenticationToken;
import com.fc.redap.utils.Constant;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import org.apache.shiro.SecurityUtils;
import org.apache.shiro.subject.Subject;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;

@RestController
@RequestMapping("/api/auth")
@Api(value="用户登录相关的API", tags={"用户登录接口"})
public class LoginController {

    @Autowired
    ISessionEntityService sessionService;

    @Autowired
    ISmsHistoryService smsHistoryService;

    @ApiOperation(value = "POST LoginReq 登录",
            notes = " REST 方式登录。" +
                    "使用方式: <ul>" +
                    "<li><i>loginMethod: 登陆类型，必填。 'BY_USERNAME' - 用户名密码登陆 / 'BY_PHONE'-手机号码密码登陆 / 'BY_SMS_CODE'-手机号码验证码登陆</i></li>" +
                    "<li><i>username: 用户名， BY_USERNAME登陆时必填</i></li>" +
                    "<li><i>phone: 手机号码， BY_PHONE登陆时必填</i></li>" +
                    "<li><i>password: 密码, BY_USERNAME和BY_PHONE登陆时必填 </i></li>" +
                    "<li><i>smsCode: 短信验证码, BY_SMS_CODE登陆时必填</i></li>" +
                    "</ul>",
            response = ResponseJson.class,
            httpMethod = "POST",
            consumes = "application/json",
            produces = "application/json",
            code = 200
    )

    @PostMapping("/login")
    public ResponseJson doPostLogin(@RequestBody LoginRequest loginReq) {
        if(StringUtils.isEmpty(loginReq.getLoginMethod())) {
            throw new ResponseException("LoginType不能为空!");
        } else if (!Constant.LoginMethod.USER_NAME_PASSWORD.getValue().equals(loginReq.getLoginMethod())
                && !Constant.LoginMethod.PHONE_PASSWORD.getValue().equals(loginReq.getLoginMethod())
                && !Constant.LoginMethod.PHONE_SMS_CODE.getValue().equals(loginReq.getLoginMethod())) {
            throw new ResponseException("LoginType的值不正确, 请注意参数!");
        }

        String userName = null;
        if(Constant.LoginMethod.PHONE_PASSWORD.getValue().equals(loginReq.getLoginMethod())) {
            // 手机号码，密码登陆
            if(StringUtils.isEmpty(loginReq.getPhone())) {
                throw new ResponseException("手机号码不能为空!");
            }
            if(StringUtils.isEmpty(loginReq.getPassword())) {
                throw new ResponseException("密码不能为空!");
            }
            userName = loginReq.getPhone();
        } else if (Constant.LoginMethod.USER_NAME_PASSWORD.getValue().equals(loginReq.getLoginMethod())) {
            // 用户名密码登陆
            if(StringUtils.isEmpty(loginReq.getUsername())) {
                throw new ResponseException("用户名不能为空!");
            }
            if(StringUtils.isEmpty(loginReq.getPassword())) {
                throw new ResponseException("密码不能为空!");
            }
            userName = loginReq.getUsername();
        } else if (Constant.LoginMethod.PHONE_SMS_CODE.getValue().equals(loginReq.getLoginMethod())) {
            // 手机号码，验证码登陆
            if(StringUtils.isEmpty(loginReq.getPhone())) {
                throw new ResponseException("手机号码不能为空!");
            }
            if(StringUtils.isEmpty(loginReq.getSmsCode())) {
                throw new ResponseException("验证码不能为空!");
            }

            SmsHistoryEntity sms = smsHistoryService.queryByMobileAndCode(loginReq.getPhone(), loginReq.getSmsCode());
            if(sms == null){
                throw new ResponseException("验证码或手机号码不正确!");
            }
            userName = loginReq.getPhone();
        }
        MyAuthenticationToken authToken = this.createToken(userName, loginReq.getPassword(), loginReq.getRememberMe() == null ? false : true, loginReq.getSmsCode(), loginReq.getLoginMethod());

        Subject subject = SecurityUtils.getSubject();
        subject.login(authToken);
        final LoginResponse loginResponse = new LoginResponse();
        loginResponse.setSid(subject.getSession().getId().toString());
        loginResponse.setCreateTime(subject.getSession().getStartTimestamp());
        ResponseJson responseJson = new ResponseJson();
        responseJson.setSuccess(true);
        return responseJson.success(loginResponse);
    }

    protected MyAuthenticationToken createToken(String username, String password, Boolean rememberMe, String smsCode, String loginMethod) {
        ServletRequestAttributes requestAttributes = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes();
        String host = requestAttributes.getRequest().getRemoteHost();
        return new MyAuthenticationToken(username, password, rememberMe, host,loginMethod, smsCode);
    }
}
